﻿using System;
using System.Net;
using System.Text;
using System.IO;

namespace FlickrWP7.Core
{
    public class Photos
    {

        public enum HasAccess
        {
            Nobody = 0,
            FriendsAndFamily=1,
            Contacts = 2,
            Everybody = 3
        }

        public enum Content
        {
            Photo = 1,
            Screenshot = 2,
            Other = 3
        }

        public enum Units
        {
            Mi,
            Km
        }

        public enum GeoContext
        {
            Everywhere,
            NotDefined,
            Indoors,
            Outdoors
        }

        public enum HasGeo
        {
            Undefined,
            True,
            False
        }
        
        public enum Contacts
        {
            All,
            FriendsAndFamily
        }

        public enum TagMode
        {
            Any,
            All
        }

        public enum Sort
        {
            Undefined,
            DatePostedAsc,
            DatePostedDesc,
            DateTakenAsc,
            DateTakenDesc,
            InterestingnessAsc,
            InterestingnessDesc
        }

        public enum SafetyLevel
        {
            Undefined = 0,
            Safe = 1,
            Moderate = 2,
            Restricted = 3
        }

        public enum PrivacyFilter
        {
            Undefined = 0,
            Public = 1,
            PrivateVisibleToFriends = 2,
            PrivateVisibleToFamily = 3,
            PrivateVisibleToBoth = 4,
            CompletelyPrivate = 5
        }

        public enum Media
        {
            All,
            Audio,
            Video
        }

        public enum ContentType
        {
            Undefined = 0,
            Photos = 1,
            Screenshots = 2,
            Other = 3,
            PhotosAndScreenshots = 4,
            ScreenshotsAndOther = 5,
            PhotosAndOther = 6,
            All = 7
        }

         HelperDelegate helperDelegateInstance;

        public  string PhotoResult { get; set; }

        public  void SetTags(string apiKey, string authToken, string signature, string photoID, string[] tags, HelperDelegate helperDelegate)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.setTags&api_key={0}&format=json&auth_token={1}&api_sig={2}&photo_id={3}",
                    apiKey, authToken, signature,photoID);

            string toAdd = "&tags=";
            for (int i = 0; i < tags.Length; i++)
            {
                if (i != tags.Length - 1)
                    toAdd += tags[i] + ",";
                else
                    toAdd += tags[i];
            }

            URL += toAdd;

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void AddTags(string apiKey, string authToken, string signature, string photoID, string[] tags, HelperDelegate helperDelegate)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.addTags&api_key={0}&format=json&auth_token={1}&api_sig={2}&photo_id={3}",
                    apiKey, authToken, signature, photoID);

            string toAdd = "&tags=";
            for (int i = 0; i < tags.Length; i++)
            {
                if (i != tags.Length - 1)
                    toAdd += tags[i] + ",";
                else
                    toAdd += tags[i];
            }

            URL += toAdd;

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void Delete(string apiKey, string authToken, string signature, string photoID, HelperDelegate helperDelegate)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.delete&api_key={0}&format=json&auth_token={1}&api_sig={2}&photo_id={3}",
                    apiKey, authToken, signature, photoID);

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void GetAllContexts(string apiKey, string authToken, string signature, string photoID, HelperDelegate helperDelegate)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.getAllContexts&api_key={0}&format=json&auth_token={1}&api_sig={2}&photo_id={3}",
                    apiKey, authToken, signature, photoID);

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void GetContactsPhotos(string apiKey, string authToken, string signature, HelperDelegate helperDelegate,
            int count = 0, bool justFriends = false, bool singlePhoto = false, bool includeSelf = false, string[] extras = null)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.getContactsPhotos&api_key={0}&format=json&auth_token={1}&api_sig={2}",
                    apiKey, authToken, signature);

            if (count != 0)
            {
                URL += "&count=" + count.ToString();
            }
            if (justFriends != false)
            {
                URL += "&just_friends=1";
            }
            if (singlePhoto != false)
            {
                URL += "&single_photo=1";
            }
            if (includeSelf != false)
            {
                URL += "&include_self=1";
            }

            if (extras != null)
            {
                string toAdd = "&extras=";
                for (int i = 0; i < extras.Length; i++)
                {
                    if (i != extras.Length - 1)
                        toAdd += extras[i] + ",";
                    else
                        toAdd += extras[i];
                }
                URL += toAdd;
            }

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void GetContactsPublicPhotos(string apiKey, string userID, HelperDelegate helperDelegate, int count = 0, 
            bool justFriends = false, bool singlePhoto = false, bool includeSelf = false, string[] extras = null)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.getContactsPublicPhotos&api_key={0}&format=json&user_id={1}",
                    apiKey,userID);

            if (count != 0)
            {
                URL += "&count=" + count.ToString();
            }
            if (justFriends != false)
            {
                URL += "&just_friends=1";
            }
            if (singlePhoto != false)
            {
                URL += "&single_photo=1";
            }
            if (includeSelf != false)
            {
                URL += "&include_self=1";
            }

            if (extras != null)
            {
                string toAdd = "&extras=";
                for (int i = 0; i < extras.Length; i++)
                {
                    if (i != extras.Length - 1)
                        toAdd += extras[i] + ",";
                    else
                        toAdd += extras[i];
                }
                URL += toAdd;
            }

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void GetContext(string apiKey, string photoID, HelperDelegate helperDelegate)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.getContext&api_key={0}&format=json&photo_id={1}",
                    apiKey, photoID);

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void GetCounts(string apiKey, string authToken, string signature, string photoID, HelperDelegate helperDelegate, string[] dates = null, string[] takenDates = null)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.getCounts&api_key={0}&format=json&auth_token={1}&api_sig={2}&photo_id={3}",
                    apiKey, authToken, signature, photoID);

            if (dates != null)
            {
                string toAdd = "&dates=";
                for (int i = 0; i < dates.Length; i++)
                {
                    if (i != dates.Length - 1)
                        toAdd += dates[i] + ",";
                    else
                        toAdd += dates[i];
                }
                URL += toAdd;
            }

            if (takenDates != null)
            {
                string toAdd = "&taken_dates=";
                for (int i = 0; i < takenDates.Length; i++)
                {
                    if (i != takenDates.Length - 1)
                        toAdd += takenDates[i] + ",";
                    else
                        toAdd += takenDates[i];
                }
                URL += toAdd;
            }

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void GetExif(string apiKey, string photoID, HelperDelegate helperDelegate, string secret = "")
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.getExif&api_key={0}&format=json&photo_id={1}",
                    apiKey, photoID);

            if (secret != "")
            {
                URL += "&secret=" + secret;
            }

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void GetFavorites(string apiKey, string photoID, HelperDelegate helperDelegate, string page = "", string perPage ="")
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.getFavorites&api_key={0}&format=json&photo_id={1}",
                    apiKey, photoID);

            if (page != "")
            {
                URL += "&page=" + page;
            }
            if (perPage != "")
            {
                URL += "&perPage=" + perPage;
            }

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void GetInfo(string apiKey, string photoID, HelperDelegate helperDelegate, string secret = "")
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.getInfo&api_key={0}&format=json&photo_id={1}",
                    apiKey, photoID);

            if (secret != "")
            {
                URL += "&secret=" + secret;
            }

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void GetNotInSet(string apiKey, string authToken, string signature,
    HelperDelegate helperDelegate, string[] extras = null, string maxUploadDate = "", string minTakenDate = "", string maxTakenDate = "", PrivacyFilter privacyFilter = PrivacyFilter.Undefined,
    Media media = Media.All, string minUploadDate = "", string page = "", string perPage ="")
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.getNotInSet&api_key={0}&api_sig={1}&auth_token={2}&format=json",
                    apiKey, signature, authToken);

            if (extras != null)
            {
                string toAdd = "&extras=";
                for (int i = 0; i < extras.Length; i++)
                {
                    if (i != extras.Length - 1)
                        toAdd += extras[i] + ",";
                    else
                        toAdd += extras[i];
                }
                URL += toAdd;
            }


            if (maxUploadDate != "")
                URL += "&max_upload_date=" + maxUploadDate;
            if (minTakenDate != "")
                URL += "&min_taken_date=" + minTakenDate;
            if (maxTakenDate != "")
                URL += "&max_taken_date=" + maxTakenDate;
            if (privacyFilter != PrivacyFilter.Undefined)
                URL += "&privacy_filter=" + ((int)privacyFilter).ToString();
            if (media != Media.All)
                URL += "&media=" + media.ToString().ToLower();
            if (minUploadDate != "")
                URL += "&min_upload_date=" + maxUploadDate;
            if (page != "")
                URL += "&page=" + page;
            if (perPage != "")
                URL += "&per_page=" + perPage;

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void GetPermissions(string apiKey, string authToken, string signature, string photoID, HelperDelegate helperDelegate)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.getPerms&api_key={0}&format=json&photo_id={1}&auth_token={2}&api_sig={3}",
                    apiKey, photoID,authToken,signature);

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void SetSafetyLevel(string apiKey, string authToken, string signature, string photoID, HelperDelegate helperDelegate, SafetyLevel safetyLevel = SafetyLevel.Undefined, bool hidden = false)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.setSafetyLevel&api_key={0}&format=json&photo_id={1}&auth_token={2}&api_sig={3}",
                    apiKey, photoID, authToken, signature);

            if (safetyLevel != SafetyLevel.Undefined)
            {
                URL += "&safety_level=" + ((int)safetyLevel).ToString();
            }
            if (hidden)
            {
                URL += "&hidden=1";
            }
            client.DownloadStringAsync(new Uri(URL));
        }

        public  void GetRecent(string apiKey, HelperDelegate helperDelegate, string page = "", string perPage = "", string[] extras = null)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.getRecent&api_key={0}&format=json",
                    apiKey);

            if (page != "")
                URL += "&page=" + page;
            if (perPage != "")
                URL += "&per_page=" + perPage;

            if (extras != null)
            {
                string toAdd = "&extras=";
                for (int i = 0; i < extras.Length; i++)
                {
                    if (i != extras.Length - 1)
                        toAdd += extras[i] + ",";
                    else
                        toAdd += extras[i];
                }
                URL += toAdd;
            }

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void GetSizes(string apiKey, string photoID, HelperDelegate helperDelegate)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.getSizes&api_key={0}&format=json&photo_id={1}",
                    apiKey, photoID);

            client.DownloadStringAsync(new Uri(URL));
        }


        public  void GetUntagged(string apiKey, string authToken, string signature,
HelperDelegate helperDelegate, string[] extras = null, string maxUploadDate = "", string minTakenDate = "", string maxTakenDate = "", PrivacyFilter privacyFilter = PrivacyFilter.Undefined,
Media media = Media.All, string minUploadDate = "", string page = "", string perPage = "")
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.getUntagged&api_key={0}&api_sig={1}&auth_token={2}&format=json",
                    apiKey, signature, authToken);

            if (extras != null)
            {
                string toAdd = "&extras=";
                for (int i = 0; i < extras.Length; i++)
                {
                    if (i != extras.Length - 1)
                        toAdd += extras[i] + ",";
                    else
                        toAdd += extras[i];
                }
                URL += toAdd;
            }

            if (maxUploadDate != "")
                URL += "&max_upload_date=" + maxUploadDate;
            if (minTakenDate != "")
                URL += "&min_taken_date=" + minTakenDate;
            if (maxTakenDate != "")
                URL += "&max_taken_date=" + maxTakenDate;
            if (privacyFilter != PrivacyFilter.Undefined)
                URL += "&privacy_filter=" + ((int)privacyFilter).ToString();
            if (media != Media.All)
                URL += "&media=" + media.ToString().ToLower();
            if (minUploadDate != "")
                URL += "&min_upload_date=" + maxUploadDate;
            if (page != "")
                URL += "&page=" + page;
            if (perPage != "")
                URL += "&per_page=" + perPage;

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void GetWithGeoData(string apiKey, string authToken, string signature,
HelperDelegate helperDelegate, string[] extras = null, string maxUploadDate = "", string minTakenDate = "", string maxTakenDate = "", PrivacyFilter privacyFilter = PrivacyFilter.Undefined,
Media media = Media.All, string minUploadDate = "", string page = "", string perPage = "", Sort sort = Sort.Undefined)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.getWithGeoData&api_key={0}&api_sig={1}&auth_token={2}&format=json",
                    apiKey, signature, authToken);

            if (extras != null)
            {
                string toAdd = "&extras=";
                for (int i = 0; i < extras.Length; i++)
                {
                    if (i != extras.Length - 1)
                        toAdd += extras[i] + ",";
                    else
                        toAdd += extras[i];
                }
                URL += toAdd;
            }

            if (maxUploadDate != "")
                URL += "&max_upload_date=" + maxUploadDate;
            if (minTakenDate != "")
                URL += "&min_taken_date=" + minTakenDate;
            if (maxTakenDate != "")
                URL += "&max_taken_date=" + maxTakenDate;
            if (privacyFilter != PrivacyFilter.Undefined)
                URL += "&privacy_filter=" + ((int)privacyFilter).ToString();
            if (media != Media.All)
                URL += "&media=" + media.ToString().ToLower();
            if (minUploadDate != "")
                URL += "&min_upload_date=" + maxUploadDate;
            if (page != "")
                URL += "&page=" + page;
            if (perPage != "")
                URL += "&per_page=" + perPage;
            if (sort != Sort.Undefined)
            {
                URL += "&sort=";

                switch (sort)
                {
                    case (Sort.DatePostedAsc):
                        {
                            URL += "date-posted-asc";
                            break;
                        }
                    case (Sort.DatePostedDesc):
                        {
                            URL += "date-posted-desc";
                            break;
                        }
                    case (Sort.DateTakenAsc):
                        {
                            URL += "date-taken-asc";
                            break;
                        }
                    case (Sort.DateTakenDesc):
                        {
                            URL += "date-taken-desc";
                            break;
                        }
                    case (Sort.InterestingnessAsc):
                        {
                            URL += "interestingness-asc";
                            break;
                        }
                    case (Sort.InterestingnessDesc):
                        {
                            URL += "interestingness-desc";
                            break;
                        }
                }
            }

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void GetWithoutGeoData(string apiKey, string authToken, string signature,
HelperDelegate helperDelegate, string[] extras = null, string maxUploadDate = "", string minTakenDate = "", string maxTakenDate = "", PrivacyFilter privacyFilter = PrivacyFilter.Undefined,
Media media = Media.All, string minUploadDate = "", string page = "", string perPage = "", Sort sort = Sort.Undefined)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.getWithoutGeoData&api_key={0}&api_sig={1}&auth_token={2}&format=json",
                    apiKey, signature, authToken);

            if (extras != null)
            {
                string toAdd = "&extras=";
                for (int i = 0; i < extras.Length; i++)
                {
                    if (i != extras.Length - 1)
                        toAdd += extras[i] + ",";
                    else
                        toAdd += extras[i];
                }
                URL += toAdd;
            }

            if (maxUploadDate != "")
                URL += "&max_upload_date=" + maxUploadDate;
            if (minTakenDate != "")
                URL += "&min_taken_date=" + minTakenDate;
            if (maxTakenDate != "")
                URL += "&max_taken_date=" + maxTakenDate;
            if (privacyFilter != PrivacyFilter.Undefined)
                URL += "&privacy_filter=" + ((int)privacyFilter).ToString();
            if (media != Media.All)
                URL += "&media=" + media.ToString().ToLower();
            if (minUploadDate != "")
                URL += "&min_upload_date=" + maxUploadDate;
            if (page != "")
                URL += "&page=" + page;
            if (perPage != "")
                URL += "&per_page=" + perPage;
            if (sort != Sort.Undefined)
            {
                URL += "&sort=";

                switch (sort)
                {
                    case (Sort.DatePostedAsc):
                        {
                            URL += "date-posted-asc";
                            break;
                        }
                    case (Sort.DatePostedDesc):
                        {
                            URL += "date-posted-desc";
                            break;
                        }
                    case (Sort.DateTakenAsc):
                        {
                            URL += "date-taken-asc";
                            break;
                        }
                    case (Sort.DateTakenDesc):
                        {
                            URL += "date-taken-desc";
                            break;
                        }
                    case (Sort.InterestingnessAsc):
                        {
                            URL += "interestingness-asc";
                            break;
                        }
                    case (Sort.InterestingnessDesc):
                        {
                            URL += "interestingness-desc";
                            break;
                        }
                }
            }

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void RecentlyUpdated(string apiKey, string authToken, string signature, string minDate, HelperDelegate helperDelegate,
            string[] extras = null, string page="", string perPage="")
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.recentlyUpdated&api_key={0}&format=json&auth_token={1}&api_sig={2}&min_date={3}",
                    apiKey, authToken,signature,minDate);

            if (extras != null)
            {
                string toAdd = "&extras=";
                for (int i = 0; i < extras.Length; i++)
                {
                    if (i != extras.Length - 1)
                        toAdd += extras[i] + ",";
                    else
                        toAdd += extras[i];
                }
                URL += toAdd;
            }

            if (page != "")
                URL += "&page=" + page;
            if (perPage != "")
                URL += "&per_page=" + perPage;

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void RemoveTag(string apiKey, string authToken, string signature, string tagID, HelperDelegate helperDelegate)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.removeTag&api_key={0}&format=json&auth_token={1}&api_sig={2}&tag_id={3}",
                    apiKey, authToken, signature,tagID);

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void Search(string apiKey, string authToken, string signature, HelperDelegate helperDelegate, TagMode tagMode = TagMode.Any, string text = "", string[] tags = null, string userID = "", string[] extras = null, string maxUploadDate = "", string minTakenDate = "", string maxTakenDate = "", PrivacyFilter privacyFilter = PrivacyFilter.Undefined, Media media = Media.All, string minUploadDate = "", string page = "", string perPage = "", Sort sort = Sort.Undefined, string license = "", string[] bbox = null, string accuracy = "", SafetyLevel safeSearch = SafetyLevel.Undefined, ContentType contentType = ContentType.Undefined, string machineTags = "", TagMode machineTagMode = TagMode.Any, string groupID = "", Contacts contacts = Contacts.All, string woeID = "", string placeID = "", HasGeo hasGeo = HasGeo.Undefined, GeoContext geoTag = GeoContext.Everywhere, string lon = "", string lat="", string radius = "", Units radiusUnits = Units.Km, bool isCommons = false, bool inGallery= false, bool isGetty = false)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.search&api_key={0}&api_sig={1}&auth_token={2}&format=json",
                    apiKey, signature, authToken);

            if (isCommons)
            {
                URL += "&is_commons=true";
            }
            if (inGallery)
            {
                URL += "&in_gallery=true";
            }
            if (isGetty)
            {
                URL += "&is_getty=true";
            }
            if (radiusUnits != Units.Km)
            {
                URL += "&radius_units=" + radiusUnits.ToString().ToLower();
            }
            if (lon != "")
            {
                URL += "&lon=" + lon;
            }
            if (lat != "")
            {
                URL += "&lat=" + lat;
            }
            if (radius != "")
            {
                URL += "&radius=" + radius;
            }
            if (geoTag != GeoContext.Everywhere)
            {
                switch(geoTag)
                {
                    case (GeoContext.Indoors):
                        {
                            URL += "&geo_context=1";
                            break;
                        }
                    case (GeoContext.Outdoors):
                        {
                            URL += "&geo_context=2";
                            break;
                        }
                    case (GeoContext.NotDefined):
                        {
                            URL += "&geo_context=0";
                            break;
                        }
                }
            }
            if (hasGeo != HasGeo.Undefined)
            {
                if (hasGeo == HasGeo.True)
                {
                    URL += "&has_geo=1";
                }
                else
                {
                    URL += "&has_geo=0";
                }
            }
            if (woeID != "")
            {
                URL += "&woe_id=" + woeID;
            }
            if (placeID != "")
            {
                URL += "&place_id=" + placeID;
            }
            if (contacts != Contacts.All)
            {
                URL += "&contacts=" + contacts;
            }
            if (groupID != "")
            {
                URL += "&group_id=" + groupID;
            }
            if (machineTagMode != TagMode.Any)
            {
                URL += "&machine_tag_mode=all";
            }
            if (machineTags != "")
            {
                URL += "&machine_tags=" + machineTags;
            }
            if (contentType != ContentType.Undefined)
            {
                URL += "&content_type=" + ((int)contentType).ToString();
            }
            if (safeSearch != SafetyLevel.Undefined)
            {
                URL += "&safe_search=" + ((int)safeSearch).ToString();
            }
            if (license != "")
            {
                URL += license;
            }
            if (text != "")
            {
                URL += "&text=" + text;
            }
            if (accuracy != "")
            {
                URL += "&accuracy=" + accuracy;
            }
            if (bbox != null)
            {
                string toAdd = "&bbox=";
                for (int i = 0; i < bbox.Length; i++)
                {
                    if (i != bbox.Length - 1)
                        toAdd += bbox[i] + ",";
                    else
                        toAdd += bbox[i];
                }
                URL += toAdd;
            }

            if (extras != null)
            {
                string toAdd = "&extras=";
                for (int i = 0; i < extras.Length; i++)
                {
                    if (i != extras.Length - 1)
                        toAdd += extras[i] + ",";
                    else
                        toAdd += extras[i];
                }
                URL += toAdd;
            }

            if (tagMode != TagMode.Any)
            {
                URL += "&tag_mode=all";
            }
            if (tags != null)
            {
                string toAdd = "&tags=";
                for (int i = 0; i < tags.Length; i++)
                {
                    if (i != tags.Length - 1)
                        toAdd += tags[i] + ",";
                    else
                        toAdd += tags[i];
                }
            }
            if (userID != "")
            {
                URL += "&user_id=" + userID;
            }
            if (maxUploadDate != "")
                URL += "&max_upload_date=" + maxUploadDate;
            if (minTakenDate != "")
                URL += "&min_taken_date=" + minTakenDate;
            if (maxTakenDate != "")
                URL += "&max_taken_date=" + maxTakenDate;
            if (privacyFilter != PrivacyFilter.Undefined)
                URL += "&privacy_filter=" + ((int)privacyFilter).ToString();
            if (media != Media.All)
                URL += "&media=" + media.ToString().ToLower();
            if (minUploadDate != "")
                URL += "&min_upload_date=" + maxUploadDate;
            if (page != "")
                URL += "&page=" + page;
            if (perPage != "")
                URL += "&per_page=" + perPage;
            if (sort != Sort.Undefined)
            {
                URL += "&sort=";

                switch (sort)
                {
                    case (Sort.DatePostedAsc):
                        {
                            URL += "date-posted-asc";
                            break;
                        }
                    case (Sort.DatePostedDesc):
                        {
                            URL += "date-posted-desc";
                            break;
                        }
                    case (Sort.DateTakenAsc):
                        {
                            URL += "date-taken-asc";
                            break;
                        }
                    case (Sort.DateTakenDesc):
                        {
                            URL += "date-taken-desc";
                            break;
                        }
                    case (Sort.InterestingnessAsc):
                        {
                            URL += "interestingness-asc";
                            break;
                        }
                    case (Sort.InterestingnessDesc):
                        {
                            URL += "interestingness-desc";
                            break;
                        }
                }
            }

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void SetContentType(string apiKey, string authToken, string signature, string photoID, Content content, HelperDelegate helperDelegate)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.setContentType&api_key={0}&format=json&photo_id={1}&auth_token={2}&api_sig={3}&content_type={4}",
                    apiKey, photoID, authToken,signature,((int)content).ToString());

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void SetDates(string apiKey, string authToken, string signature, string photoID, HelperDelegate helperDelegate, string datePosted = "", string dateTaken = "", string dateTakenGranularity = "")
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.setDates&api_key={0}&format=json&photo_id={1}&auth_token={2}&api_sig={3}",
                    apiKey, photoID, authToken, signature);

            if (datePosted != "")
            {
                URL += "&date_posted=" + datePosted;
            }
            if (dateTaken != "")
            {
                URL += "&date_taken=" + dateTaken;
            }
            if (dateTakenGranularity != "")
            {
                URL += "&date_taken_granularity=" + dateTakenGranularity;
            }

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void SetMeta(string apiKey, string authToken, string signature, string photoID, string title, string description, HelperDelegate helperDelegate)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.setMeta&api_key={0}&format=json&photo_id={1}&auth_token={2}&api_sig={3}&title={4}&description={5}",
                    apiKey, photoID, authToken, signature, title, description);

            client.DownloadStringAsync(new Uri(URL));
        }

        public  void SetPermissions(string apiKey, string authToken, string signature, string photoID, bool isPublic, bool isFriend, bool isFamily, HasAccess canComment, HasAccess canAddMeta, HelperDelegate helperDelegate)
        {
            helperDelegateInstance = helperDelegate;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.photos.setPerm&api_key={0}&format=json&photo_id={1}&auth_token={2}&api_sig={3}&perm_comment={4}&perm_addmeta={5}",
                    apiKey, photoID, authToken, signature, ((int)canComment).ToString(),((int)canAddMeta).ToString());

            if (isPublic)
            {
                URL += "&is_public=true";
            }
            if (isFriend)
            {
                URL += "&is_friend=true";
            }
            if (isFamily)
            {
                URL += "&is_family=true";
            }

            client.DownloadStringAsync(new Uri(URL));
        }

         void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            PhotoResult = e.Result;
            helperDelegateInstance();
        }
    }
}
